package com.sh.rbac.core.common.util;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.sh.rbac.core.common.exception.CustomException;
import com.sh.rbac.core.common.result.ResultCodeEnum;
import jakarta.servlet.http.HttpServletResponse;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;

/**
 * Excel  工具类
 *
 * @author wb
 * @since 2025-05-25
 */
public class ExcelUtils {


    /**
     * 导出数据到Excel
     *
     * @param response         响应对象
     * @param fileNamePrefix   文件名前缀
     * @param headDataClass    Excel头部数据类
     * @param cellWriteHandler 单元格样式处理器
     * @param dataList         数据列表
     * @param <T>              Excel映射类泛型
     * @param <S>              数据列表泛型
     */
    public static <T, S> void exportDataToExcel(HttpServletResponse response, String fileNamePrefix, Class<T> headDataClass, CellWriteHandler cellWriteHandler, List<S> dataList) {
        try {
            // 生成文件名
            String timestamp = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN);
            String randomSuffix = RandomUtil.randomNumbers(5);
            String filename = fileNamePrefix + "-" + timestamp + randomSuffix;

            // 编码文件名以支持中文
            String encodedFileName = URLEncoder.encode(filename, StandardCharsets.UTF_8);

            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-Disposition", "attachment;filename=" + encodedFileName + ".xlsx");

            // 写入Excel到输出流
            EasyExcel.write(response.getOutputStream())
                    .head(headDataClass)
                    .excelType(ExcelTypeEnum.XLSX)
                    .registerWriteHandler(cellWriteHandler)
                    .sheet(fileNamePrefix + "-sheet")
                    .doWrite(dataList);

        } catch (Exception e) {
            throw new CustomException(ResultCodeEnum.DATA_EXPORT_ERROR);
        }
    }

}
